{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "70ec90a4",
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import requests\n",
    "\n",
    "from dotenv import load_dotenv\n",
    "from bs4 import BeautifulSoup\n",
    "from IPython.display import Markdown\n",
    "from openai import OpenAI"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ead9f914",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Standard headers to fetch a website\n",
    "headers = {\n",
    "    \"User-Agent\": \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36\"\n",
    "}\n",
    "\n",
    "def fetch_website_contents(url):\n",
    "    \"\"\"\n",
    "    Return the title and contents of the website at the given url;\n",
    "    truncate to 2,000 characters as a sensible limit\n",
    "    \"\"\"\n",
    "    response = requests.get(url, headers=headers)\n",
    "    soup = BeautifulSoup(response.content, \"html.parser\")\n",
    "    title = soup.title.string if soup.title else \"No title found\"\n",
    "    if soup.body:\n",
    "        for irrelevant in soup.body([\"script\", \"style\", \"img\", \"input\"]):\n",
    "            irrelevant.decompose()\n",
    "        text = soup.body.get_text(separator=\"\\n\", strip=True)\n",
    "    else:\n",
    "        text = \"\"\n",
    "    return (title + \"\\n\\n\" + text)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9cc68b05",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Load environment variables in a file called .env\n",
    "load_dotenv(override=True)\n",
    "api_key = os.getenv('OPENAI_API_KEY')\n",
    "\n",
    "# Check the key\n",
    "if not api_key:\n",
    "    print(\"No API key was found - please head over to the troubleshooting notebook in this folder to identify & fix!\")\n",
    "elif not api_key.startswith(\"sk-proj-\"):\n",
    "    print(\"An API key was found, but it doesn't start sk-proj-; please check you're using the right key - see troubleshooting notebook\")\n",
    "elif api_key.strip() != api_key:\n",
    "    print(\"An API key was found, but it looks like it might have space or tab characters at the start or end - please remove them - see troubleshooting notebook\")\n",
    "else:\n",
    "    print(\"API key found and looks good so far!\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7c344ab7",
   "metadata": {},
   "outputs": [],
   "source": [
    "website = fetch_website_contents(\"https://www.allrecipes.com/easy-5-ingredient-dinners-11799627\")\n",
    "print(website)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f759f8f9",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Define System Prompt\n",
    "system_prompt = \"\"\"\n",
    "You are a well-spoken cooking assistant that analyzes the contents of a food recipe website's meal list,\n",
    "and finds a random recipe from within that list of recipes. You return the recipe name as a header, and if you cannot follow the link\n",
    "use the internet to generate an appropriate recipe/dish summary or background in a well detailed paragraph.\n",
    "Then you can return the list of ingredients followed by the cooking instructions for both conventional methods and air fryers \n",
    "(similarly, if you cannot follow the link, then use the internet to find or generate the appropriate ingredient list and instructions).\n",
    "You do not need to select meals that include 'air fryer' in the name or already have air-fryer instructions. If a recipe does not have\n",
    "air-fryer-related instructions, use the internet to find the best way to cook the recipe on an air fryer and generate the instructions.\n",
    "Finally, display the information for that recipe. Format the ingredients (use this as a subheading) and instructions (use this as another subheading) \n",
    "into their own neatly organized tables.\n",
    "\n",
    "You ignore text that might be website-navigation related that is not related to the link to the recipe.\n",
    "\n",
    "You respond in markdown. Do not wrap the markdown in a code block!\n",
    "\"\"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d9683ce8",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Define User Prompt\n",
    "\n",
    "user_prompt_prefix = \"\"\"\n",
    "Here are the contents of a food recipe website's easy dinners list. Randomly choose one of the recipes. \n",
    "Return the recipe name, then provide a summary or background of the dish. Then return the ingredients, \n",
    "and cooking instructions for both conventional methods and air-frying.\n",
    "\"\"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6cecf0cf",
   "metadata": {},
   "outputs": [],
   "source": [
    "openai = OpenAI()\n",
    "\n",
    "messages = [\n",
    "    {\"role\": \"system\", \"content\": system_prompt},\n",
    "    {\"role\": \"user\", \"content\": user_prompt_prefix + website}\n",
    "]\n",
    "\n",
    "response = openai.chat.completions.create(model=\"gpt-5-nano\", messages=messages)\n",
    "Markdown(response.choices[0].message.content)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "llm-engineering",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
